#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <MyTextEdit.h>
#include <QIcon>
#include <QMessageBox>
#include <QDebug>
#include<QFileDialog>
#include <QTimer>
#include <QTime>
#include <QSettings>
#include <QCloseEvent>
#include <QLabel>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initWindow();
    editWindowList = new QList<MyTextEdit *>();
    windowMapper = new QSignalMapper(this);
    connect(ui->mdiArea, &QMdiArea::subWindowActivated, this, &MainWindow::activeChanged);
    connect(windowMapper, &QSignalMapper::mappedObject, this, &MainWindow::setActiveWindow);
    updateWindowMenu();
    connect(ui->menuW, &QMenu::aboutToShow, this, &MainWindow::updateWindowMenu);
    lastTime = QDateTime::currentDateTime().toString("yyyy-MM-dd");
    readSettings();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionNew_triggered()
{
    QString filePath;
    QString curTime = QDateTime::currentDateTime().toString("yyyy-MM-dd");
    if(curTime == lastTime) offset++;
    else {
        offset = 0;
        lastTime = curTime;
    }
    createEdit(tr("%1/%2_%3.txt").arg(QDir::currentPath()).arg(curTime).arg(offset), false);
}


void MainWindow::on_actionSave_triggered()
{
    if(!activeSubWindow) return;
    if(activeSubWindow->metaObject()->className() != MyTextEdit::staticMetaObject.className()){
        QMessageBox::warning(this, "保存失败", "请先选择要保存的文件");
        return;
    }
    MyTextEdit *curEdit = static_cast<MyTextEdit *>(activeSubWindow);
    if(curEdit->save()){
        QMessageBox::information(this, "保存成功","文件已保存到本地");
    }
}


void MainWindow::on_actionSaveAs_triggered()
{
    if(!activeSubWindow) return;
    if(activeSubWindow->metaObject()->className() != MyTextEdit::staticMetaObject.className()){
        QMessageBox::warning(this, "保存失败", "请先选择要保存的文件");
        return;
    }
    MyTextEdit *curEdit = static_cast<MyTextEdit *>(activeSubWindow);
    if(curEdit->saveAs()){
        QMessageBox::information(this, "保存成功","文件已保存到本地");
    }
}


void MainWindow::on_actionOpen_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                    QDir::currentPath(),
                                                    tr("Text files (*.txt)"));
    qDebug() << "要打开的文件" << fileName;
    if(!fileName.isEmpty()){
        //再判断是否是已经打开的文件，如果是，则让该edit获得焦点
        MyTextEdit * window = isExistedWindow(fileName);
        if(window){
            window->setFocus();
        }else{
            createEdit(fileName, true);
        }
    }
}

void MainWindow::activeChanged(QMdiSubWindow *subWindow)
{
    if(!subWindow){
        activeSubWindow = nullptr;
        return;
    }
    QWidget *w = subWindow->widget();
    if(w->metaObject()->className() == MyTextEdit::staticMetaObject.className()){
        MyTextEdit *window = static_cast<MyTextEdit *>(w);
        MyTextEdit *result = isExistedWindow(window->getFilePath());
        if(result) activeSubWindow = result;
    }
}

void MainWindow::createEdit(QString filePath, bool existed)
{
    MyTextEdit *newTextWindow = new MyTextEdit(ui->mdiArea, filePath, existed);
    ui->mdiArea->addSubWindow(newTextWindow);
    editWindowList->append(newTextWindow);
    newTextWindow->installEventFilter(this);
    connect(newTextWindow, &MyTextEdit::cursorPositionChanged, this, &MainWindow::showCursorPos);
    newTextWindow->show();
}

MyTextEdit *MainWindow::isExistedWindow(QString filePath) //可做优化，优化为O(1)查找
{
    MyTextEdit * window;
    MyTextEdit * result = NULL;
    for(int i = 0; i < editWindowList->length(); i++){
        window = editWindowList->at(i);
        if(window->getFilePath() == filePath){
            result = window;
            break;
        }
    }
    return result;
}

void MainWindow::deleteWindow(QString filePath)
{
    MyTextEdit * window;
    for(int i = 0; i < editWindowList->length(); i++){
        window = editWindowList->at(i);
        if(window->getFilePath() == filePath){
            editWindowList->removeAt(i);
            break;
        }
    }
}

void MainWindow::updateWindowMenu()
{
    ui->menuW->clear();
    //依次添加初始动作
    ui->menuW->addAction(ui->actionClose);
    ui->menuW->addAction(ui->actionCloseAll);
    ui->menuW->addSeparator();
    ui->menuW->addAction(ui->actionTile);
    ui->menuW->addAction(ui->actionCascade);
    ui->menuW->addSeparator();
    ui->menuW->addAction(ui->actionNext);
    ui->menuW->addAction(ui->actionPrevious);
    QAction *lastSeparator = ui->menuW->addSeparator();
    QList<QMdiSubWindow *> windows = ui->mdiArea->subWindowList();
    if(windows.isEmpty()){
        lastSeparator->setVisible(false);
        return;
    }
    QMdiSubWindow * window;
    for(int i = 0; i < windows.length(); i++){
        window = windows.at(i);
        MyTextEdit *textEdit = static_cast<MyTextEdit *>(window->widget());
        QAction *choose = ui->menuW->addAction(tr("%1. %2").arg(i + 1).arg(textEdit->getFileName()));
        choose->setCheckable(true);
        choose->setChecked(textEdit->getFilePath() == activeSubWindow->getFilePath());
        choose->connect(choose, &QAction::triggered, windowMapper, qOverload<>(&QSignalMapper::map));
        windowMapper->setMapping(choose, window);
    }
}

void MainWindow::setActiveWindow(QObject *obj)
{
    QMdiSubWindow *window = static_cast<QMdiSubWindow *>(obj);
    ui->mdiArea->setActiveSubWindow(window);
}

void MainWindow::clearOffset()
{
    offset = 0;
}

void MainWindow::showCursorPos()
{
    if(activeSubWindow){
        QString text = tr("%1: (%2行,%3列)").arg(activeSubWindow->getFileName()).arg(activeSubWindow->textCursor().blockNumber() + 1)
                                                    .arg(activeSubWindow->textCursor().columnNumber() + 1);
        ui->statusbar->showMessage(text);
    }
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    ui->mdiArea->closeAllSubWindows();
    if(ui->mdiArea->currentSubWindow()){
        event->ignore();
    }else{
        writeSettings();
        event->accept();
    }
}

bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
    if(object->metaObject()->className() ==  MyTextEdit::staticMetaObject.className()){
        MyTextEdit *window = static_cast<MyTextEdit *>(object);
        if(event->type() == QEvent::Close){
            qDebug()<<"开始处理窗口关闭事件..."<<"文件路径"<<window->getFilePath();
            deleteWindow(window->getFilePath());
        }
    }
    return false;
}


void MainWindow::on_actionUndo_triggered()
{
    if(!activeSubWindow) return;
    activeSubWindow->undo();
}


void MainWindow::on_actionRedo_triggered()
{
    if(!activeSubWindow) return;
    activeSubWindow->redo();
}


void MainWindow::on_actionCut_triggered()
{
    if(!activeSubWindow) return;
    activeSubWindow->cut();
}


void MainWindow::on_actionCopy_triggered()
{
    if(!activeSubWindow) return;
    activeSubWindow->copy();
}


void MainWindow::on_actionPaste_triggered()
{
    if(!activeSubWindow) return;
    activeSubWindow->paste();
}


void MainWindow::on_actionClose_triggered()
{
    if(!activeSubWindow) return;
    ui->mdiArea->closeActiveSubWindow();
}



void MainWindow::on_actionNext_triggered()
{
    ui->mdiArea->activateNextSubWindow();
}


void MainWindow::on_actionPrevious_triggered()
{
    ui->mdiArea->activatePreviousSubWindow();
}


void MainWindow::on_actionCloseAll_triggered()
{
    ui->mdiArea->closeAllSubWindows();
}


void MainWindow::on_actionTile_triggered()
{
    ui->mdiArea->tileSubWindows();
}


void MainWindow::on_actionCascade_triggered()
{
    ui->mdiArea->cascadeSubWindows();
}

void MainWindow::on_actionAbout_triggered() // 关于菜单
{
    QMessageBox::about(this,tr("关于本软件"),tr("欢迎访问我们的网站：www.yafeilinux.com"));
}

void MainWindow::on_actionAboutQt_triggered() // 关于Qt菜单
{
    qApp->aboutQt(); // 这里的qApp是QApplication对象的全局指针，
        // 这行代码相当于QApplication::aboutQt();
}

void MainWindow::readSettings()
{
    QSettings settings("zhuhj", "mdiArea");
    if(settings.contains("rect")) this->setGeometry(settings.value("rect").toRect());
}

void MainWindow::writeSettings()
{
    QSettings settings("zhuhj", "mdiArea");
    settings.setValue("rect", this->geometry());
}

void MainWindow::initWindow()
{
    setWindowTitle(tr("多文档编辑器"));

    // 我们在工具栏上单击鼠标右键时，可以关闭工具栏
    ui->toolBar->setWindowTitle(tr("工具栏"));

    // 当多文档区域的内容超出可视区域后，出现滚动条
    ui->mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    ui->mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

    ui->statusbar->showMessage(tr("欢迎使用多文档编辑器"));

    QLabel *label = new QLabel(this);
    label->setFrameStyle(QFrame::Box | QFrame::Sunken);
    label->setText(
        tr("<a href=\"http://www.yafeilinux.com\">yafeilinux.com</a>"));
    label->setTextFormat(Qt::RichText); // 标签文本为富文本
    label->setOpenExternalLinks(true);  // 可以打开外部链接
    ui->statusbar->addPermanentWidget(label);


    ui->actionNew->setStatusTip(tr("创建一个文件"));
    ui->actionOpen->setStatusTip(tr("打开一个已经存在的文件"));
    ui->actionSave->setStatusTip(tr("保存文档到硬盘"));
    ui->actionSaveAs->setStatusTip(tr("以新的名称保存文档"));
    ui->actionExit->setStatusTip(tr("退出应用程序"));
    ui->actionUndo->setStatusTip(tr("撤销先前的操作"));
    ui->actionRedo->setStatusTip(tr("恢复先前的操作"));
    ui->actionCut->setStatusTip(tr("剪切选中的内容到剪贴板"));
    ui->actionCopy->setStatusTip(tr("复制选中的内容到剪贴板"));
    ui->actionPaste->setStatusTip(tr("粘贴剪贴板的内容到当前位置"));
    ui->actionClose->setStatusTip(tr("关闭活动窗口"));
    ui->actionCloseAll->setStatusTip(tr("关闭所有窗口"));
    ui->actionTile->setStatusTip(tr("平铺所有窗口"));
    ui->actionCascade->setStatusTip(tr("层叠所有窗口"));
    ui->actionNext->setStatusTip(tr("将焦点移动到下一个窗口"));
    ui->actionPrevious->setStatusTip(tr("将焦点移动到前一个窗口"));
    ui->actionAbout->setStatusTip(tr("显示本软件的介绍"));
    ui->actionAboutQt->setStatusTip(tr("显示Qt的介绍"));

}

